#include "app_buffer.h"
#include <stdlib.h>
#include "log/log.h"
#include <string.h>

// 初始化互斥锁
static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;

Buffer *app_buffer_init(int size)
{
    if (size <= 0)
    {
        log_warn("app_buffer_init size <= 0");
        return NULL;
    }

    // 初始Buffer结构体: 动态分配内存
    Buffer *buffer = malloc(sizeof(Buffer));
    if (buffer == NULL)
    {
        log_warn("app_buffer_init malloc buffer failed");
        return NULL; // 失败返回
    }

    // 初始化buffer中的lock: 拷贝niit_lock
    memcpy(&(buffer->lock), &init_lock, sizeof(pthread_mutex_t));

    // 初始化buffer中的ptr: 动态分配内存
    buffer->ptr = malloc(size);
    if (buffer->ptr == NULL)
    {
        log_warn("app_buffer_init malloc buffer->ptr failed");
        free(buffer); // 释放buffer
        // app_buffer_free(buffer);
        return NULL; // 失败返回
    }

    // 初始化其它成员
    buffer->total_size = size;
    buffer->len = 0;
    buffer->offset = 0;

    log_debug("app_buffer_init  int buffer success");
    // 初始buffer
    return buffer;
}

void app_buffer_free(Buffer *buffer)
{
    if (buffer == NULL)
    {
        log_warn("app_buffer_free buffer is NULL");
        return;
    }
    // 释放buffer中的ptr
    if(buffer->ptr)
    {
        free(buffer->ptr);
    }

    // 释放buffer   lock是buffer内存的一部分，不需要单独释放
    free(buffer);
    log_debug("app_buffer_free free buffer success");
}

int app_buffer_write(Buffer *buffer, const char *data, int len)
{
    // 进行参数的合法性检查
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_warn("app_buffer_write param error");
        return -1;
    }
    if (len>buffer->total_size - buffer->len)
    {
        log_warn("app_buffer_write fail, len too long!");
        return -1;
    }

    // 加锁
    pthread_mutex_lock(&(buffer->lock));

    // 计算出写入的起始位置
    int write_start = buffer->offset + buffer->len;
    // 如果超过最大值， 修正write_start
    if (write_start > buffer->total_size-1)
    {
        write_start = write_start - buffer->total_size;
    }
    // 将数据写入buffer， 判断是一段写入还是二段写
    if (write_start + len > buffer->total_size) // 二段写入
    {
        int len1 = buffer->total_size - write_start;
        memcpy(buffer->ptr + write_start, data, len1);
        memcpy(buffer->ptr, data + len1, len - len1);
    }
    else  // 一段写入
    {
        memcpy(buffer->ptr + write_start, data, len);
    }
    // 更新buffer的len     不用更新offset
    buffer->len += len;

    // 解锁
    pthread_mutex_unlock(&(buffer->lock));

    log_debug("app_buffer_write len=%d, offset=%d, len=%d, ptr=%s", len, 
        buffer->offset, buffer->len, buffer->ptr);

    return 0;
}

int app_buffer_read(Buffer *buffer, char *data, int len)
{
    // 进行参数的合法性检查
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_warn("app_buffer_read param error");
        return -1;
    }

    // 如果len超过buffer的len， 修正len
    if (len > buffer->len)
    {
        len = buffer->len;
    }

    // 加锁
    pthread_mutex_lock(&(buffer->lock));
    
    // 读取数据， 判断是一段读取还是二段读取
    if (buffer->offset + len > buffer->total_size) // 二段读取
    {
        // 读取第一段的长度
        int len1 = buffer->total_size - buffer->offset;
        memcpy(data, buffer->ptr + buffer->offset, len1);
        memcpy(data + len1, buffer->ptr, len - len1);
        buffer->offset = len - len1;
    }
    else // 一段读取
    {
        memcpy(data, buffer->ptr + buffer->offset, len);
        buffer->offset += len;
    }

    // 更新buffer的len
    buffer->len -= len;

    log_debug("app_buffer_read len=%d, offset=%d, len=%d, ptr=%s", len, 
        buffer->offset, buffer->len, buffer->ptr);

    // 解锁
    pthread_mutex_unlock(&(buffer->lock));

    return len;
}